from rest_framework import serializers
from ..models.unitModel import *
from ..config.message_config import Search_message, Search_message_type


class UnitListQuerySerializer(serializers.Serializer):
    unit_name = serializers.CharField(required=False, allow_blank=True)
    sei_id = serializers.CharField(required=False, allow_blank=True)
    unit_symbol = serializers.CharField(required=False, allow_blank=True)
    dimension = serializers.JSONField(required=False)
    page_size = serializers.IntegerField(
        required=False, max_value=50, min_value=1)
    current_page = serializers.IntegerField(required=False)
    sort_prop = serializers.CharField(required=False, allow_blank=True)
    sort_order = serializers.CharField(required=False, allow_blank=True)

    def validate(self, attrs):
        filter_flag = True
        page_flag = True
        if "unit_name" in attrs:
            attrs["unit_name"] = attrs["unit_name"].strip()
            if attrs["unit_name"] == "":
                attrs.pop("unit_name")
        if "sei_id" in attrs:
            attrs["sei_id"] = attrs["sei_id"].strip()
            if attrs["sei_id"] == "":
                attrs.pop("sei_id")
        if "unit_symbol" in attrs:
            attrs["unit_symbol"] = attrs["unit_symbol"].strip()
            if attrs["unit_symbol"] == "":
                attrs.pop("unit_symbol")
        if "dimension" in attrs:
            if len(attrs["dimension"]) == 0:
                attrs.pop("dimension")
            else:
                attrs["dimension"] = attrs["dimension"][0]
        if ("unit_name" not in attrs or attrs["unit_name"] == "") and ("sei_id" not in attrs or attrs["sei_id"] == "") and ("unit_symbol" not in attrs or attrs["unit_symbol"] == "") and ("dimension" not in attrs or attrs["dimension"] == ""):
            filter_flag = False
        if ("page_size" not in attrs):
            page_flag = False
        if not filter_flag and not page_flag:
            raise serializers.ValidationError({
                'detail': "{} : {}".format(Search_message_type.get("SEARCH_FAIL"), Search_message.get("SEARCH_BROAD"))
            })
        try:
            attrs = super().validate(attrs)
        except serializers.ValidationError as e:
            raise serializers.ValidationError({
                'detail': "{} : {},{}".format(Search_message_type.get("SEARCH_FAIL"), Search_message.get("SEARCH_PARAM_ERROR"), str(e.detail))
            })
        return attrs

    @classmethod
    def get_query_fields(self):
        return [{"title": "单位名称：", "dataIndex": "unit_name", "type": "CharField"},
                {"title": "单位编码：", "dataIndex": "sei_id", "type": "CharField"},
                {"title": "单位符号：", "dataIndex": "unit_symbol", "type": "CharField"},
                {"title": "量纲：", "dataIndex": "dimension", "type": "CharField"},]


class UnitListSerializer(serializers.ModelSerializer):
    unit_name = serializers.SerializerMethodField()
    dimension = serializers.SerializerMethodField()
    conversion_source = serializers.SerializerMethodField()

    class Meta:
        model = Unit
        fields = ['uuid', 'unit_name', 'unit_symbol', 'dimension', 'sei_id',
                  'conversion_source', 'unit_description', 'unit_comment']
        
    def get_unit_name(self, obj):
        return obj.show_short_name()

    def get_dimension(self, obj):
        return obj.dimension.show_short_name()

    def get_conversion_source(self, obj):
        if obj.root_unit == None:
            return "无"
        else:
            return "{}({}) = {}({}) * {} + {}".format(obj.show_short_name(), obj.unit_symbol, obj.root_unit.show_short_name(), obj.root_unit.unit_symbol, obj.conversion_factor, obj.conversion_offset)

    @classmethod
    def get_extra_fields_info(self):
        return [
            {"title":"单位名称", "dataIndex":"unit_name", "type":"CharField"},
            {"title": "换算关系", "dataIndex": "conversion_source", "type": "TextField"},]


class UnitCreateSerializer(serializers.ModelSerializer):
    prefix = serializers.JSONField(required=False)
    dimension = serializers.JSONField(required=False)
    root_unit = serializers.JSONField(required=False)
    conversion_factor = serializers.FloatField(required=False, allow_null=True)
    conversion_offset = serializers.FloatField(required=False, allow_null=True)

    class Meta:
        model = Unit
        fields = ['unit_name', 'unit_name_en', 'unit_symbol', 'sei_id', 'prefix', 'is_show', 'dimension', 'root_unit',
                  'conversion_factor', 'conversion_offset', 'unit_description', 'unit_description_en', 'unit_comment', ]

    def to_internal_value(self, data):
        data = super().to_internal_value(data)
        for field_name in self.fields:
            value = data.get(field_name)
            if isinstance(value, str):
                data[field_name] = value.strip()

        return data
    
    def validate(self, attrs):
        if "prefix" in attrs:
            if len(attrs["prefix"]) == 0:
                attrs.pop("prefix")
            else:
                attrs["prefix"] = attrs["prefix"][0]
        if "dimension" in attrs:
            if len(attrs["dimension"]) == 0:
                attrs.pop("dimension")
            else:
                attrs["dimension"] = attrs["dimension"][0]
        if "root_unit" in attrs:
            if len(attrs["root_unit"]) == 0:
                attrs.pop("root_unit")
            else:
                attrs["root_unit"] = attrs["root_unit"][0]
        if "conversion_factor" in attrs:
            if attrs["conversion_factor"] == None:
                attrs.pop("conversion_factor")
        if "conversion_offset" in attrs:
            if attrs["conversion_offset"] == None:
                attrs.pop("conversion_offset")
        if "root_unit" not in attrs or "conversion_factor" not in attrs or "conversion_offset" not in attrs:
            if "root_unit" in attrs:
                attrs.pop("root_unit")
            if "conversion_factor" in attrs:
                attrs.pop("conversion_factor")
            if "conversion_offset" in attrs:
                attrs.pop("conversion_offset")
        if "conversion_factor" in attrs:
            if attrs["conversion_factor"] == 0:
                raise serializers.ValidationError(
                    {"conversion_factor": "换算乘数不能为0"})
        try:
            attrs = super().validate(attrs)
        except Exception as e:
            raise serializers.ValidationError(str(e))
        return attrs

    @classmethod
    def get_extra_fields_info(self):
        return []


class UnitModifyInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Unit
        fields = ['unit_name', 'unit_name_en', 'unit_symbol', 'sei_id', 'prefix', 'is_show', 'dimension', 'root_unit',
                  'conversion_factor', 'conversion_offset', 'unit_description', 'unit_description_en', 'unit_comment', ]


class UnitModifyInfoInSerializer(serializers.ModelSerializer):
    prefix = serializers.JSONField(required=False)
    dimension = serializers.JSONField(required=False)
    root_unit = serializers.JSONField(required=False)
    conversion_factor = serializers.FloatField(required=False, allow_null=True)
    conversion_offset = serializers.FloatField(required=False, allow_null=True)

    class Meta:
        model = Unit
        fields = ['unit_name', 'unit_name_en', 'unit_symbol', 'sei_id', 'prefix', 'is_show', 'dimension', 'root_unit',
                  'conversion_factor', 'conversion_offset', 'unit_description', 'unit_description_en', 'unit_comment', ]

    def to_internal_value(self, data):
        data = super().to_internal_value(data)
        for field_name in self.fields:
            value = data.get(field_name)
            if isinstance(value, str):
                data[field_name] = value.strip()

        return data
    
    def validate(self, attrs):
        if "prefix" in attrs:
            if len(attrs["prefix"]) == 0:
                attrs.pop("prefix")
            else:
                attrs["prefix"] = attrs["prefix"][0]
        if "dimension" in attrs:
            if len(attrs["dimension"]) == 0:
                attrs.pop("dimension")
            else:
                attrs["dimension"] = attrs["dimension"][0]
        if "root_unit" in attrs:
            if len(attrs["root_unit"]) == 0:
                attrs.pop("root_unit")
            else:
                attrs["root_unit"] = attrs["root_unit"][0]
        if "conversion_factor" in attrs:
            if attrs["conversion_factor"] == None:
                attrs.pop("conversion_factor")
        if "conversion_offset" in attrs:
            if attrs["conversion_offset"] == None:
                attrs.pop("conversion_offset")
        if "root_unit" not in attrs or "conversion_factor" not in attrs or "conversion_offset" not in attrs:
            if "root_unit" in attrs:
                attrs.pop("root_unit")
            if "conversion_factor" in attrs:
                attrs.pop("conversion_factor")
            if "conversion_offset" in attrs:
                attrs.pop("conversion_offset")
        if "conversion_factor" in attrs:
            if attrs["conversion_factor"] == 0:
                raise serializers.ValidationError(
                    {"conversion_factor": "换算乘数不能为0"})
        try:
            attrs = super().validate(attrs)
        except Exception as e:
            raise serializers.ValidationError(str(e))
        return attrs


class UnitInfoSerializer(serializers.ModelSerializer):
    dimension = serializers.SerializerMethodField()
    prefix = serializers.SerializerMethodField()
    conversion_source = serializers.SerializerMethodField()
    is_show = serializers.SerializerMethodField()
    create_person = serializers.SerializerMethodField()
    modify_person = serializers.SerializerMethodField()

    class Meta:
        model = Unit
        fields = ['unit_name', 'unit_name_en', 'unit_symbol', 'sei_id', 'prefix', 'dimension',
                  'is_show', 'conversion_source', 'unit_description', 'unit_description_en', 'unit_comment', 'create_person', 'create_date', 'modify_person', 'modify_date']

    def get_is_show(self, obj):
        return "是" if obj.is_show else "否"

    def get_dimension(self, obj):
        return obj.dimension.show_short_name()

    def get_prefix(self, obj):
        if obj.prefix == None:
            return "无"
        else:
            return "{}({})".format(obj.prefix.show_short_name(), obj.prefix.prefix_symbol)

    def get_conversion_source(self, obj):
        if obj.root_unit == None:
            return "无"
        else:
            return "{}({}) = {}({}) * {} + {}".format(obj.show_short_name(), obj.unit_symbol, obj.root_unit.show_short_name(), obj.root_unit.unit_symbol, obj.conversion_factor, obj.conversion_offset)

    def get_create_person(self, obj):
        return obj.create_person.user_name

    def get_modify_person(self, obj):
        return obj.modify_person.user_name

    @classmethod
    def get_extra_fields_info(self):
        return [{"title": "换算关系", "dataIndex": "conversion_source", "type": "TextField"},]
